/**
 * Created by IntelliJ IDEA.
 * Time: 20:05
 * @Author: xyb
 * @Version: 2017/6/28
 * To change this template use File | Settings | File Templates.
 */

(function (doc) {

    var $view;
    var views;
    var $footer;
    var $inputContent;
    var $sendMsgBtn;
    var $msg;
    var pageNum;
    var lockUpDrag;

    var lastMsgTime = null;// 最后消息的时间

    var scrollHeight = null;
    var scrollHeight_new = null;


    /*录音*/

    var MIN_SOUND_TIME = 800;// 录音时间低于800毫秒
    var mediaRec = null;// 录音对象
    var startTimestamp = null;// 开始录音时间
    var stopTimestamp = null;// 结束录音时间
    var stopTimer = null;// 延迟隐藏
    var recordCancel = false;// 录音错误

    var $soundAlert = null;// 录音提示模块
    var $audioTips = null;// 录音提示文字


    function onInit() {
        // 初始化元素
        onInitData();
        // 获取与当前好友的聊天信息
        onShowCurrChatMsg();
        // 切换发送类型
        onTabToggleSenderType();
        // 创建WebSocket连接
        onCreateConnect();
        // 录音模块
        onRecordMedia();
        // 播放语音
        playAudio();
    }


    // 初始化元素
    function onInitData() {
        app.setViewTitle(views.params.name);// 设置标题栏为好友的名字
        $footer = $view.find('.footer');// 获取底部footer
        $inputContent = $footer.find('.text_input');// 文字输入框
        $sendMsgBtn = $footer.find('#send_msg_btn');// 文字发送按钮
        $msg = $view.find("#msg");// 聊天信息显示框

        $soundAlert = $view.find('#sound-alert').get(0);// 录音提示模块
        $audioTips = $view.find("#audio-tips").get(0);// 录音提示模块中的文字
        pageNum = 1;// 初始页
        lockUpDrag = true;
    }

    function onShowCurrChatMsg() {

        //  获取好友id
        var toUserId = views.params.id;
        var userId = backService.localLoginInfo.id;

        // 获取与当前好友聊天信息
        backService.message.showCurrChatMsg(userId, toUserId, pageNum, function (json) {
            var jsons = json.data;
            if (jsons != null && jsons.length > 0) {
                lastMsgTime = new Date(0);
                for (var i in jsons) {
                    var json = jsons[i];
                    // console.log(json);
                    if (backService.localLoginInfo.id == json.userId) {// 自己发送的消息right
                        onSendMsgToScreen(json, 0);
                    } else {// 好友发送的left
                        onSendMsgToScreen(json, 1);
                    }
                }
            } else {
                lastMsgTime = new Date();
            }

            scrollHeight_new = $('#msg').get(0).scrollHeight;
            $view.find("#msg").scrollTop(scrollHeight_new - scrollHeight - 100);

            if (pageNum == 1) {
                onScrollTop();
            }

            pageNum++;
            lockUpDrag = true;
        }, function (error) {
            app.showToast(error.msg);
        });

    }

    /**
     * 切换发送类型
     */
    function onTabToggleSenderType() {
        // 切换
        $footer.find('.tab_btn').on("click", function () {
            var $this = $(this);
            if (!$this.parent().hasClass("hide")) {
                $this.parent().addClass("hide").siblings(".citem").removeClass("hide");
            }
            if ($this.hasClass("edit_btn")) {
                $inputContent.focus();
                if ($inputContent.val() != "" && $inputContent.val() != null) {
                    $footer.find('.rest_fun').addClass("hide").siblings(".right_item").removeClass("hide");
                }
            } else {
                $footer.find('.rest_fun').removeClass("hide").siblings(".right_item").addClass("hide");
            }
        });


        // 切换发送按钮和附加功能
        $inputContent.bind("input propertychange", function () {
            var val = $(this).val();
            if (val != "" && val != null) {
                $footer.find('.rest_fun').addClass("hide").siblings(".right_item").removeClass("hide");
            } else {
                $footer.find('.rest_fun').removeClass("hide").siblings(".right_item").addClass("hide");
            }
        });

        $inputContent.on("click", function () {
            setTimeout(onScrollTop, 500);
        });

    }

    //创建连接
    function onCreateConnect() {
        //连接创建后调用
        backService.socket.onopen = function (event) {
            onOpen(event);
        };
        //接收到服务器消息后调用
        backService.socket.onmessage = function (event) {
            onMessage(event);
        };
        //关闭连接的时候调用
        backService.socket.onclose = function (event) {
            onClose(event);
        };
        //出错时调用
        backService.socket.onerror = function (event) {
            onError(event);
        };

        /**
         * 发送消息
         */
        $sendMsgBtn.on("click", sendTextMsg);
    }

    /**
     * 连接成功
     * @param e
     */
    function onOpen(e) {
        console.log(e);
        onScrollTop();
    }

    /**
     * 推送消息
     * @param e
     */
    function onMessage(e) {
        var data = $.parseJSON(e.data);
        // console.log(data);
        if (data.userId == null || data.userId == undefined || data.userId == "") {
            //===系统消息
            $view.find("#msg").append("<li style='list-style: none'><b>" + data.createTime + "</b><em>系统消息：</em><span>" + data.content + "</span></li>");
        } else if (data.userId == backService.localLoginInfo.id) {// 发送给自己一份
            onSendMsgToScreen(data, 0, "push");
        } else {// 他人发送给我的
            onSendMsgToScreen(data, 1, "push");
        }
    }

    /**
     * 关闭连接
     * @param e
     */
    function onClose(e) {

        console.log(e);
    }

    /**
     * 发生错误
     * @param e
     */
    function onError(e) {
        console.log(e)
    }

    /**
     * 显示消息到指定的位置
     * @param data
     * @param index
     */
    function onSendMsgToScreen(data, index, status) {

        var lastTime = pub.date.formatHHMM(new Date(lastMsgTime));
        var time = pub.date.formatHHMM(new Date(data.createTime));


        if (index == 0) {// 发送给自己的消息
            onSendMsgSon(data, status);
        } else if (index == 1) {// 发送给朋友的消息
            onSendMsgFriend(data, status);
        }

        if (lastTime != time) {
            var $newTime = null;
            if (onIsToDay(new Date(data.createTime))) {
                $newTime = time;
            } else {
                $newTime = pub.date.formatDateTime(data.createTime)
            }
            var $chatTime = $('<div class="chat_time"><span class="text">' + $newTime + '</span></div>');
            if (status) {
                // $chatTime.appendTo($msg);
                $chatTime.insertBefore($msg.find('.chat_item:last-child'));
                onScrollTop();
            } else {
                $msg.prepend($chatTime);
            }
            lastMsgTime = data.createTime;
        }

    }

    /**
     * 发送给自己的消息
     * @param data
     */
    function onSendMsgSon(data, status) {

        var $chat_right = null;
        if (data.type == 1) {// 文字
            $chat_right = $('<div class="chat_item chat_right">' +
                '<div class="chat_media">' +
                '<img src="img/message/show/head.jpg" alt="">' +
                '</div>' +
                '<div class="chat_inner">' +
                '<div class="chat_name hide"></div>' +
                '<div class="chat_content">' +
                '<div class="chat_arrow"></div>' +
                data.content +
                '</div>' +
                '<div class="chat_status">' +
                '</div>' +
                '</div>' +
                '</div>');
        } else if (data.type == 2) {// 语音
            $chat_right = $('<div class="chat_item chat_right">' +
                '<div class="chat_media">' +
                '<img src="img/message/show/head.jpg" alt="">' +
                '</div>' +
                '<div class="chat_inner">' +
                '<div class="chat_name hide"></div>' +
                '<div class="chat_content audio" voiceId=' + data.voiceFileId + '>' +
                '<div class="chat_arrow"></div>' +
                '</div>' +
                '<div class="chat_status">' +
                data.duration +
                '"</div>' +
                '</div>' +
                '</div>');
        }

        if (status) {
            $chat_right.appendTo($msg);
            onScrollTop();
        } else {
            $msg.prepend($chat_right);
        }
    }

    /**
     * 发送给朋友的消息
     * @param data
     */
    function onSendMsgFriend(data, status) {
        var $chat_left = null;
        if (data.type == 1) {// 文字
            $chat_left = $('<div class="chat_item chat_left">' +
                '<div class="chat_media">' +
                '<img src="img/message/show/head.jpg" alt="">' +
                '</div>' +
                '<div class="chat_inner">' +
                '<div class="chat_name hide">' + data.nickName + '</div>' +
                '<div class="chat_content">' +
                '<div class="chat_arrow"></div>' +
                data.content +
                '</div>' +
                '</div>' +
                '</div>');
        } else if (data.type == 2) {// 语音
            $chat_left = $('<div class="chat_item chat_left">' +
                '<div class="chat_media">' +
                '<img src="img/message/show/head.jpg" alt="">' +
                '</div>' +
                '<div class="chat_inner">' +
                '<div class="chat_name hide">' + data.nickName + '</div>' +
                '<div class="chat_content audio" voiceId=' + data.voiceFileId + '>' +
                '<div class="chat_arrow"></div>' +
                '</div>' +
                '<div class="chat_status">' +
                data.duration +
                '"</div>' +
                '</div>' +
                '</div>');
        }
        if (status) {
            $chat_left.appendTo($msg);
            onScrollTop();
        } else {
            $msg.prepend($chat_left);
        }
    }

    /**
     * 页面移动最底部
     */
    function onScrollTop() {
        $view.find("#msg").scrollTop($view.find("#msg")[0].scrollHeight);
    }

    /**
     * 发送文字消息
     */
    function sendTextMsg() {
        $inputContent.focus();

        var msg = {
            userId: backService.localLoginInfo.id,
            toUserId: views.params.id,
            content: $inputContent.val(),
            type: 1,
            status: 0,//未读
            nickName: backService.localLoginInfo.nickName,
            avatar: backService.localLoginInfo.avatar
        };
        backService.socket.send(JSON.stringify(msg));
        $inputContent.val("");

    }

    // 发送语音消息
    function sendRecordMsg(data) {
        var base64Str = data.replace('data:audio/mpeg;base64,', '');
        var duration = Math.round(Number((stopTimestamp - startTimestamp) / 1000));
        var msg = {
            userId: backService.localLoginInfo.id,
            toUserId: views.params.id,
            content: base64Str,
            type: 2,
            status: 0,//未读
            nickName: backService.localLoginInfo.nickName,
            avatar: backService.localLoginInfo.avatar,
            duration: duration
        };
        backService.socket.send(JSON.stringify(msg));
    }

    // 控制录音弹出框是否播放
    var set$soundAlertVisable = function (show) {
        if (show) {
            $soundAlert.style.display = 'block';
            $soundAlert.style.opacity = 1;
        } else {
            $soundAlert.style.opacity = 0;
            //  完成再真正隐藏
            setTimeout(function () {
                $soundAlert.style.display = 'none';
            }, 500);
        }
    };

    // 录音模块
    function onRecordMedia() {

        // 创建音频文件名
        var fileName = null;

        // 按住录音（长按开始录音）
        $view.find('#recorder').get(0).addEventListener('touchstart', function () {
            fileName = new Date().getTime() + "chat-speak.mp3";// 创建录音文件名
            recordCancel = false;// 初始化退出录音，true录音失败，false，录音成功
            // 清除隐藏录音提示框，解决上一次录音延时隐藏导致新一轮录音出现显示录音提示冲突
            if (stopTimer) clearTimeout(stopTimer);

            $audioTips.innerHTML = "手指上划，取消发送";
            $soundAlert.classList.remove('rprogress-sigh');
            set$soundAlertVisable(true);

            startTimestamp = (new Date()).getTime();// 开始录音时间
            // 获取当前设备的录音对象
            mediaRec = new Media(fileName,
                // 录音成功返回
                function () {
                    console.log("Audio Success: " + fileName);
                },
                // 录音失败返回
                function (err) {
                    console.log("Audio Error: " + err.code);
                });

            // 开始录音
            mediaRec.startRecord();
        });

        // 释放保存（松手保存）
        $view.find('#recorder').get(0).addEventListener('touchend', function () {
            if ($audioTips.classList.contains("cancel")) {
                $audioTips.classList.remove("cancel");
                $audioTips.innerHTML = "手指上划，取消发送";
            }
            // 判断录音时间
            stopTimestamp = (new Date()).getTime();
            if (stopTimestamp - startTimestamp < MIN_SOUND_TIME) {// 录音时间低于800毫秒
                mediaRec.release();// 释放录音文件
                // 录音时间太短，删除保存的音频文件
                onDelRecordMedia(fileName);
                $audioTips.innerHTML = "录音时间太短";
                $soundAlert.classList.add('rprogress-sigh');
                recordCancel = true;
                stopTimer = setTimeout(function () {
                    set$soundAlertVisable(false);
                }, 800);
            } else {
                // 隐藏录音提示框
                set$soundAlertVisable(false);
                if (recordCancel) { // 如果手指上滑，并且已经松开了手指，则取消发送
                    onDelRecordMedia(fileName);
                    mediaRec.stopRecord();
                    return false;
                }
                // 读取音频文件
                Audio2dataURL(fileName);
            }
            // 停止录音
            mediaRec.stopRecord();
        });

        // 拖动屏幕（手指上划，取消发送）
        document.body.addEventListener('drag', function (event) {
            if (Math.abs(event.detail.deltaY) > 50) {// 手指距离按钮50像素
                if (!recordCancel) {
                    recordCancel = true;
                    if (!$audioTips.classList.contains("cancel")) {
                        $audioTips.classList.add("cancel");
                    }
                    $audioTips.innerHTML = "松开手指，取消发送";
                }
            } else {
                if (recordCancel) {// 如果手指移回按钮旁
                    recordCancel = false;
                    if ($audioTips.classList.contains("cancel")) {
                        $audioTips.classList.remove("cancel");
                    }
                    $audioTips.innerHTML = "手指上划，取消发送";
                }
            }
            if (lockUpDrag) {
                if ($view.find("#msg").get(0).scrollTop == 0) {
                    if (Math.abs(event.detail.deltaY) > 50) {
                        lockUpDrag = false;
                        scrollHeight = $('#msg').get(0).scrollHeight;
                        setTimeout(onShowCurrChatMsg, 500);
                        return false;
                    }
                }
            }
        }, false);


    }

    /**
     * 录音语音文件转base64字符串
     * @param {Object} path
     */
    function Audio2dataURL(fileName) {

        resolveLocalFileSystemURL(cordova.file.externalRootDirectory, function (dirEntry) {
            dirEntry.getFile(fileName, {}, function (fileEntry) {
                fileEntry.file(function (file) {
                    var reader = new FileReader();
                    reader.onloadend = function () {
                        // console.log("读取文件base64 :" + this.result);
                        sendRecordMsg(this.result);
                    }
                    reader.readAsDataURL(file);
                }, errorHandler);
            }, errorHandler);
        }, errorHandler);
    }


    /**
     * 录音时间太短，删除保存的音频文件
     */
    function onDelRecordMedia(fileName) {
        resolveLocalFileSystemURL(cordova.file.externalRootDirectory, function (dirEntry) {
            dirEntry.getFile(fileName, null, function (fileEntry) {
                fileEntry.remove(function () {
                    console.log("删除文件成功!");
                }, errorHandler);
            }, errorHandler);
        }, errorHandler)
    }


    function errorHandler(e) {
        console.log(e)
    }

    /**
     * 播放音频
     * @param {Object} path
     */
    function playAudio() {
        var $msg = $view.find('#msg');
        var $this;
        var $voice = $view.find('#voice');
        $msg.on("click", '.chat_content.audio', function () {
            $this = $(this);
            if ($(this).hasClass("play")) {
                $voice.get(0).pause();
                $voice.get(0).currentTime = 0;
                $this.removeClass("play");
            } else {
                var voiceId = $(this).attr("voiceid");
                var src = backService.getFileUrl(voiceId);
                $(this).addClass("play");
                $voice.attr("src", src);
                $voice.get(0).play();
            }
        });

        $voice.get(0).addEventListener("ended", function () {
            $this.removeClass("play");
        });
    }

    /**
     * 是否当天
     * @param time
     */
    function onIsToDay(time) {
        var toDayTime = new Date();
        var status = true;
        if (time.getFullYear() != toDayTime.getFullYear()) {
            status = false;
            return status;
        }
        if (time.getMonth() != toDayTime.getMonth()) {
            status = false;
            return status;
        }
        if (time.getDate() != toDayTime.getDate()) {
            status = false;
            return status;
        }
        return status;
    }

    window.onViewInit_message_show = function (view) {
        $view = view.element;
        views = view;
    };

    window.onViewShow_message_show = function (view) {
        $view = view.element;
        onInit();
    };

})(document);